/*用户服务模块*/
#include "head.h"

/*用户功能选择*/
int function(int sockfd_2, int id)
{
    int i = 0;
    int ret;
    char buf[8] = {0};
    if ((ret = recv(sockfd_2, buf, sizeof(buf), 0)) == -1) // 5.接收客户端发送的信息,看看是什么功能
    {
        printf("%s\n", buf);
        perror("recv");
        close(sockfd_2);
        return 9;
    }
    else if (ret == 0)
    {
        return 9; // 当客户端断开，返回9，退出功能选项，服务器也断开
    }
    i = atoi(buf);
    printf("%d\n", i);

    switch (i)
    {
    case 1:
    {
        // printf("功能：下载文件\n");
        if (9 == download(sockfd_2, id))
            return 9;
    }
    break;
    case 2:
    {
        // printf("功能：上传文件\n");
        if (9 == upload(sockfd_2, id))
            return 9;
    }
    break;
    case 3:
    {
        // printf("功能：退出\n");
        return 9;
    }
    case 4:
    {
        // printf("功能：查看目录\n");
        look_dir(sockfd_2, id);
    }
    break;
    case 9:
    {
        // printf("账号设置\n");
        info_3(sockfd_2, id);
    }
    break;
    default:
        printf("输入无效\n");
        break;
    }
    return 0;
}

/*用户下载文件模块*/
int download(int sockfd_2, int id)
{
    int file_size=0;
    int read_size=0;
    char action[7] = {0};
    char file[42] = {0};
    char file_size_str[32];
    char buffer[1024] = {0};
    char file_name[32] = {0};

    if (-1 == send(sockfd_2, "请输入要下载的文件名:", 33, 0))
    {
        perror("send");
        return 9;
    }
    
    if (0 >= recv(sockfd_2, file_name, sizeof(file_name) - 1, 0)) // 接收客户端要下载的文件名
    {
        perror("recv");
        printf("客户端接收下载文件名失败\n");
        return 9;
    }
    printf("客户端要下载的文件名:%s\n", file_name);

    file_track(file_name, id, 0); // 将相关业务服务，加入表中

    sprintf(file, "./file/%s", file_name);

    FILE *fp;
    fp = fopen(file, "rb");
    fseek(fp, 0, SEEK_END);
    file_size = ftell(fp); // 计算文件字数
    fseek(fp, 0, SEEK_SET);

    sprintf(file_size_str, "%d", file_size); // 数字转字符串
    int ret = send(sockfd_2, file_size_str, strlen(file_size_str) + 1, 0);
    if (ret < 0)
    {
        perror("send");
        return 9;
    }

    
    if (0 >= recv(sockfd_2, action, sizeof(action), 0)) // 接收客户端已经准备
    {
        perror("recv");
        close(sockfd_2);
        return 9;
    }

    while ((read_size = fread(buffer, 1, 1024, fp)) > 0)
    {
        if (send(sockfd_2, buffer, read_size, 0) != read_size)
        {
            perror("send");
            close(sockfd_2);
        }
    }
    sleep(5);
    fclose(fp);
    printf("发送完成————————\n");
    return 0;
}

/*用户上传文件模块*/
int upload(int sockfd_2, int id)
{
    int i=0;
    int ret=0;
    int file_num=0;
    int recv_size=0;
    int file_size=0;
    int recv_how_size=0;
    char file_name[32];
    char file[42] = {0};
    char buf[1024] = {0};
    char file_size_str[32]; // 接收要下载的文件字数
    
    file_size = atoi(file_size_str);
    
    if (-1 == send(sockfd_2, "请输入要上传的文件名", 31, 0))
    {
        perror("send");
        close(sockfd_2);
        return 9;
    }

    

    if ((i = recv(sockfd_2, file_name, sizeof(file_name) - 1, 0)) <= 0) // 接收客户端要上传的文件名
    {
        perror("recv");
        printf("接收文件名失败\n");
        return 9;
    }
    printf("客户端要上传的文件名:%s\n", file_name);
    file_track(file_name, id, 1); // 将相关业务操作加入到数据库中


    ret = recv(sockfd_2, file_size_str, sizeof(file_size_str) - 1, 0);
    if (ret <= 0)
    {
        perror("recv");
        printf("客户端接收要下载文件失败\n");
        return 9;
    }
    printf("本次要上传的文件字数：%s\n", file_size_str);
    

    FILE *fp;
    sprintf(file, "./file/%s", file_name);
    if ((fp = fopen(file, "wb")) == NULL)
    {
        perror("fopen");
        return 9;
    }
    file_num = file_size;

    ret = send(sockfd_2, "111111", 7, 0); // 给客户端发送消息做好准备
    if (ret < 0)
    {
        perror("send");
        return 9;
    }
    while (file_num > 0)
    {
        recv_how_size = file_num < 1024 ? file_num : 1024;
        recv_size = recv(sockfd_2, buf, recv_how_size, 0);
        if (recv_size <= 0)
        {
            perror("recv");
            fclose(fp);
            printf("上传文件失败\n");
            return 9;
        }
        fwrite(buf, 1, recv_size, fp);
        file_num -= recv_size;
    }
    fclose(fp);
    file_data(); // 将添加的文件加入数据库中
    printf("上传文件完成\n");

    return 0;
}

void file_track(char *buf, int id, int op)
{
    char buf_1[16] = {"文件信息"};
    char query[148];
    char *a;
    MYSQL *mysql = mysql_op(buf_1);
    char const *q[] = {"download", "upload"};
    printf("%s\n", buf);
    sprintf(query, "insert into track (id,file_name,file_op,time) values('%d','%s','%s','%s')", id, buf, q[op], get_time(2));
    if (mysql_real_query(mysql, query, strlen(query)))
    {
        printf("%s\n", mysql_error(mysql));
        printf("记录失败\n");
    }
    mysql_close(mysql);
    return;
}

/*用户查看文件目录*/
void look_dir(int sockfd_2, int id)
{
    int m=0;
    MYSQL_ROW row;                  //用来存放记录
    unsigned int fnum;
    char buf[24] = {0};
    char action[15] = {0};
    char buf_1[16] = {"文件信息"};
    char file_num[5];               // 将文件个数发给客户端
    if (-1 == send(sockfd_2, "查看目录选项:", 36, 0))
    {
        perror("send");
        close(sockfd_2);
        return;
    }

    if (0 >= recv(sockfd_2, buf, sizeof(buf), 0)) // 接收客户端要看目录
    {
        perror("recv");
        printf("服务器接收目录请求失败\n");
        close(sockfd_2);
        return;
    }

    MYSQL *mysql = mysql_op(buf_1);               // 打开数据库

    MYSQL_RES *result = data_num(&mysql);         // 拿到结果集

    my_ulonglong rnum = mysql_num_rows(result);   // 获取记录数量

    fnum = mysql_num_fields(result); // 由result获取字段的数量
    m = (int)rnum;
    sprintf(file_num, "%d", m); // 数字转字符串

    if (-1 == send(sockfd_2, file_num, 5, 0))
    {
        perror("send");
        mysql_free_result(result);
        return;
    }

    
    if (0 >= recv(sockfd_2, action, sizeof(action), 0)) // 接收客户端已经准备
    {
        perror("recv");
        close(sockfd_2);
        mysql_free_result(result);
        return;
    }

    
    for (int i = 0; i < m; i++)
    {
        row = mysql_fetch_row(result);
        file_dir(sockfd_2, row, fnum);
    }

    mysql_free_result(result);
    mysql_close(mysql);
    sleep(1);
    printf("发送完成\n");
    return;
}

MYSQL_RES *data_num(MYSQL **mysql) // 拿到数据库结果集
{
    char query[50] = {0};
    MYSQL_RES *result;      //用来存放结果集
    sprintf(query, "select *from file");
    if (mysql_real_query(*mysql, query, strlen(query))) // mysql_real_query()函数是执行sql操作语句的函数
    {
        printf("%s\n", mysql_error(*mysql));
    }
   
    if ((result = mysql_store_result(*mysql)) == NULL) // 4.存储结果集到result中
    {                                                  // 这个result用完需要释放空间
        printf("%s\n", mysql_error(*mysql));
    }
    return result;
}

void file_dir(int sockfd_2, MYSQL_ROW row, int fnum) // 发送数据库文件信息
{
    dir info;
    strcpy(info.file_name,row[0]);
    info.file_sort = atoi(row[1]);
    info.file_root = atoi(row[2]);
    if (send(sockfd_2, &info, sizeof(dir), 0) < 0)
    {
        perror("send");
        return;
    }
    return;
}
